home *** CD-ROM | disk | FTP | other *** search
/ Apple WWDC 1996 / WWDC96_1996 (CD).toast / Technology Materials / QuickTime VR / MacOS / QuickDraw™ 3D 1.0.6F4 SDK / Samples / SampleCode / GeometryTest / GTFile.c < prev    next >
Encoding:
Text File  |  1996-02-19  |  9.4 KB  |  377 lines  |  [TEXT/MPCC]

  1. // GTFile.c, file and metafile routines
  2.  
  3.  
  4. // system headers
  5. #include <Desk.h>
  6. #include <Dialogs.h>
  7. #include <DiskInit.h>
  8. #include <Fonts.h>
  9. #include <Menus.h>
  10. #include <PictUtil.h>
  11. #include <QDOffScreen.h>
  12. #include <QuickDraw.h>
  13. #include <Resources.h>
  14. #include <SegLoad.h>
  15. #include <StandardFile.h>
  16. #include <TextEdit.h>
  17. #include <ToolUtils.h>
  18.  
  19. #include "GTSupport.h"
  20. #include "GTFile.h"
  21.  
  22. #include "QD3D.h"
  23. #include "QD3DDrawContext.h"
  24. #include "QD3DRenderer.h"
  25. #include "QD3DShader.h"
  26. #include "QD3DCamera.h"
  27. #include "QD3DLight.h"
  28. #include "QD3DGeometry.h"
  29. #include "QD3DTransform.h"
  30. #include "QD3DGroup.h"
  31. #include "QD3DMath.h"
  32.  
  33. #include "QD3DStorage.h"
  34. #include "QD3DIO.h"
  35.  
  36. //-------------------------------------------------------------------------------------------
  37. // function prototypes
  38.  
  39. static void         InitDocumentData( DocumentHdl theDocument ) ;
  40. static void         DisposeDocumentData( DocumentHdl theDocument ) ;
  41. static DocumentHdl    CreateDocument( void ) ;
  42. static Boolean         MetafileFileSpecify( FSSpec *theFile ) ;
  43.  
  44. //-------------------------------------------------------------------------------------------
  45. //
  46.  
  47. void InitDocumentData( DocumentHdl theDocument ) 
  48. {
  49.     TQ3Point3D        myOrigin = { 0, 0, 0 } ;
  50.     
  51.     // sanity check
  52.     if( theDocument == nil || (**theDocument).fWindow == nil )
  53.         return ;
  54.         
  55.     // Lock and load
  56.     HLock( (Handle)theDocument ) ;
  57.     
  58.     // sets up the 3d data for the scene
  59.     //    Create view for QuickDraw 3D.
  60.     (**theDocument).fView = MyNewView( (**theDocument).fWindow );
  61.  
  62.     // the main display group:
  63.     (**theDocument).fModel = NULL ;    
  64.     
  65.     // the drawing styles:
  66.     (**theDocument).fInterpolation = Q3InterpolationStyle_New(kQ3InterpolationStyleNone) ;
  67.     (**theDocument).fBackFacing = Q3BackfacingStyle_New(kQ3BackfacingStyleBoth ) ;
  68.     (**theDocument).fFillStyle = Q3FillStyle_New(kQ3FillStyleFilled ) ;
  69.  
  70.  
  71.     (**theDocument).fGroupScale = 1;                
  72.     (**theDocument).fGroupCenter = myOrigin ;    
  73.     
  74.     // set up an illumination shder for this document
  75.     (**theDocument).fShader = Q3PhongIllumination_New();        
  76.  
  77.     // set the rotation matrix the identity matrix
  78.     Q3Matrix4x4_SetIdentity(&(**theDocument).fRotation);    
  79.                     
  80.     // unlock the handle            
  81.     HUnlock((Handle) theDocument ) ;
  82.     
  83.     return ;
  84.     
  85. bail:
  86.     // either we failed getting the model or the view
  87.     // so we want to quit here
  88.     ExitToShell() ;
  89.     
  90. }
  91.  
  92. //-------------------------------------------------------------------------------------------
  93. //
  94.  
  95. void DisposeDocumentData( DocumentHdl theDocument )
  96. {
  97.     // Lock and load
  98.     HLock( (Handle)theDocument ) ;
  99.     
  100.     if( (**theDocument).fView ) 
  101.         Q3Object_Dispose((**theDocument).fView) ;                // the view for the scene
  102.  
  103.     if( (**theDocument).fModel )  
  104.         Q3Object_Dispose((**theDocument).fModel) ;                // object in the scene being modelled
  105.  
  106.     if( (**theDocument).fInterpolation )  
  107.         Q3Object_Dispose((**theDocument).fInterpolation) ;        // interpolation style used when rendering
  108.  
  109.     if( (**theDocument).fBackFacing )  
  110.         Q3Object_Dispose((**theDocument).fBackFacing) ;            // whether to draw shapes that face away from the camera
  111.  
  112.     if( (**theDocument).fFillStyle )  
  113.         Q3Object_Dispose((**theDocument).fFillStyle) ;            // whether drawn as solid filled object or decomposed to components
  114.  
  115.     HUnlock((Handle) theDocument ) ;
  116.     
  117.     // And free the storage used by the document handle
  118.     DisposHandle((Handle) theDocument);
  119. }
  120.  
  121. //-------------------------------------------------------------------------------------------
  122. //
  123. void HandleCloseWindow( WindowPtr theWindow )
  124. {
  125.     DocumentHdl     theDocument ;
  126.     
  127.     if( theWindow ) {
  128.         theDocument = (DocumentHdl) GetWRefCon( theWindow ) ;
  129.         DisposeWindow ( theWindow );
  130.         if( theDocument )
  131.             DisposeDocumentData( theDocument ) ;
  132.     }
  133.  
  134. }
  135.  
  136.  
  137. //-------------------------------------------------------------------------------------------
  138. // Create and init a document with the 3d stuff - gets called by both open and new
  139.  
  140. DocumentHdl    CreateDocument( void ) 
  141. {
  142.     DocumentHdl        theDocument;
  143.     WindowPtr        theWindow = nil ;
  144.     OSErr            theErr = noErr ;
  145.     
  146.     if(( theDocument = (DocumentHdl)NewHandleClear( sizeof(DocumentRec))) != nil )
  147.     {
  148.         theWindow = GetNewCWindow(128,nil,(WindowPtr)-1);
  149.         if( theWindow == nil ) 
  150.             return nil ;
  151.         
  152.         SetWRefCon( theWindow, (long)theDocument );
  153.         (**theDocument).fWindow = theWindow ;
  154.         
  155.         // initialise our document structure
  156.         InitDocumentData( theDocument ) ;
  157.     
  158.     }
  159.     else // handle the error
  160.         theErr = MemError() ;
  161.     
  162.     return theDocument ;        
  163. }
  164.  
  165. OSErr    HandleNewCommand( void )
  166. {
  167.     DocumentHdl    theDocument ;
  168.     OSErr        theErr = noErr ;
  169.     theDocument = CreateDocument() ;
  170.     if(theDocument == nil )
  171.     {
  172.         theErr = MemError() ;
  173.         if( theErr == noErr )
  174.         {
  175.             theErr = ResError() ;
  176.         }
  177.     
  178.     }
  179.     return theErr ;
  180. }
  181.  
  182. //-------------------------------------------------------------------------------------------
  183. //
  184. Boolean MetafileFileSpecify( FSSpec *theFile )
  185. {
  186.     StandardFileReply    theSFReply ;
  187.     SFTypeList            myTypes = { 'TEXT', '3DMF' } ;
  188.     const short            numTypes = 2 ;
  189.         
  190.     // Get the file name to open
  191.     StandardGetFile( nil, numTypes, myTypes, &theSFReply ) ;
  192.     
  193.     if( theSFReply.sfGood )
  194.         *theFile = theSFReply.sfFile ;
  195.     
  196.     // did the user cancel?
  197.     return theSFReply.sfGood ;
  198.     
  199. }
  200.  
  201. //-----------------------------------------------------------------------------------------------
  202. //
  203. OSErr    HandleOpenCommand( void )
  204. {
  205.     DocumentHdl    theDocument ;
  206.     OSErr        theErr = noErr ;
  207.     FSSpec        theFileSpec ;
  208.     
  209.     
  210.     theDocument = CreateDocument() ;
  211.     if(theDocument == nil )
  212.     {
  213.         theErr = MemError() ;
  214.         if( theErr == noErr )
  215.         {
  216.             theErr = ResError() ;
  217.         }
  218.         return theErr ;
  219.     }
  220.  
  221.     if(MetafileFileSpecify( &theFileSpec )) {
  222.     
  223.         WindowPtr        myWindow = (**theDocument).fWindow ;
  224.     
  225.         SetCursor(*(GetCursor(watchCursor)));
  226.         HLock((Handle)theDocument) ;
  227.         
  228.         // try to read the file into the main display group
  229.         if(((**theDocument).fModel = MyNewModelFromFile(&theFileSpec)) != NULL ) {        
  230.  
  231.             AdjustCamera(    theDocument,
  232.                             (myWindow->portRect.right - myWindow->portRect.left),
  233.                             (myWindow->portRect.bottom - myWindow->portRect.top) ) ;
  234.  
  235.             SetWTitle( myWindow, theFileSpec.name );
  236.             ShowWindow( myWindow ) ;
  237.             SetPort( myWindow ) ;
  238.     
  239.             SetCursor(&qd.arrow) ;
  240.             
  241.         }
  242.         
  243.         HUnlock((Handle)theDocument) ;
  244.         SetCursor(&qd.arrow) ;
  245.     }
  246.     return theErr ; // you should do better error checking
  247.  
  248. }    
  249.  
  250.  
  251. //-----------------------------------------------------------------------------------------------
  252. // cleaned up from IM QuickDraw 3D pp 15-5
  253. static TQ3FileObject MyGetNewFile( FSSpec *myFSSpec, TQ3Boolean *isText )
  254. {
  255.     TQ3FileObject        myFileObj;
  256.     TQ3StorageObject        myStorageObj;
  257.     OSType                myFileType;
  258.     
  259.     FInfo                fndrInfo ;
  260.  
  261.     // we assume the FSSpec passed in was valid, get the file information
  262.     // we need to know the file type, this routine may get called by an appleEvent
  263.     // handler, so we can't assume a type, we need to get it from the fsspec.
  264.     
  265.     FSpGetFInfo( myFSSpec, &fndrInfo ) ;
  266.     
  267.     // pull out the file type
  268.     
  269.     myFileType = fndrInfo.fdType ;
  270.     
  271.     // Create new storage object and new file object 
  272.     if(((myStorageObj = Q3FSSpecStorage_New( myFSSpec )) == NULL) 
  273.         || ((myFileObj = Q3File_New()) == NULL)) 
  274.     {
  275.         if (myStorageObj != NULL) 
  276.             Q3Object_Dispose(myStorageObj);
  277.         return(NULL);
  278.     }
  279.  
  280.     // Set the storage for the file object
  281.     Q3File_SetStorage(myFileObj, myStorageObj);
  282.     Q3Object_Dispose(myStorageObj);
  283.  
  284.     if ((myFileType == '3DMF') || (myFileType == 'EO3D'))
  285.         *isText = kQ3False ;
  286.     else if (myFileType == 'TEXT')
  287.         *isText = kQ3True ;
  288.  
  289.     return (myFileObj);
  290. }
  291.  
  292.  
  293. //----------------------------------------------------------------------------------
  294. // read model from file object into the supplied group
  295.  
  296. static TQ3Status MyReadModelFromFile( TQ3FileObject theFile,TQ3GroupObject myGroup)
  297. {    
  298.     if(theFile != NULL) {
  299.     
  300.         TQ3Object            myTempObj ;
  301.         TQ3Boolean            isEOF ;
  302.                 
  303.     
  304.         // read objects from the file
  305.         do {
  306.         
  307.             myTempObj = Q3File_ReadObject( theFile );
  308.             
  309.             if( myTempObj != NULL ) {
  310.                 // we only want the object in our main group if we can draw it
  311.                 if ( Q3Object_IsDrawable( myTempObj) ) 
  312.                     Q3Group_AddObject( myGroup, myTempObj ) ;
  313.                 
  314.                 // we either added the object to the main group, or we don't care
  315.                 // so we can safely dispose of the object
  316.                 Q3Object_Dispose( myTempObj ) ;
  317.             }
  318.             
  319.             // check to see if we reached the end of file yet
  320.             isEOF = Q3File_IsEndOfFile( theFile );
  321.             
  322.         } while (isEOF == kQ3False);    
  323.     }
  324.     
  325.     if( myGroup != NULL )
  326.         return kQ3Success ;
  327.     else
  328.         return kQ3Failure ;
  329. }
  330.  
  331. //----------------------------------------------------------------------------------
  332. // attach a shader to the group
  333.  
  334. static TQ3Status MyAddShaderToGroup( TQ3GroupObject group )
  335. {
  336.     TQ3ShaderObject    illuminationShader = Q3PhongIllumination_New();
  337.  
  338.     Q3Group_AddObject(group, illuminationShader);
  339.     Q3Object_Dispose(illuminationShader);
  340.     return(kQ3Success);
  341. }
  342.  
  343. //----------------------------------------------------------------------------------
  344.  
  345. static TQ3GroupObject MyNewModelFromFile(FSSpec *theFileSpec)
  346. {
  347.     TQ3GroupObject        myGroup = NULL ;
  348.     TQ3Boolean            isText = kQ3False ;
  349.     TQ3FileMode            myFileMode = 0;
  350.     TQ3FileObject        theFile;
  351.     
  352.     //    Create a ordered group for the complete model.
  353.     if ((myGroup = Q3DisplayGroup_New()) == NULL )
  354.         return NULL;
  355.         
  356.     MyAddShaderToGroup( myGroup ) ;
  357.  
  358.     theFile = MyGetNewFile( theFileSpec, &isText ) ;
  359.     
  360.     if( isText == kQ3True )
  361.         myFileMode |= kQ3FileModeText;    // is it a text metafile??    
  362.  
  363.     // Open the file object
  364.     if( Q3File_OpenRead( theFile, &myFileMode ) != kQ3Success)
  365.         return  NULL ;
  366.  
  367.     if( MyReadModelFromFile( theFile, myGroup ) == NULL)
  368.         DebugStr("\pMetafile data read is null") ;
  369.     
  370.     Q3File_Close(theFile);            // close and dispose of the file object
  371.     Q3Object_Dispose(theFile);
  372.     
  373.     return myGroup ;
  374. }
  375.  
  376.  
  377.